// Function.prototype.bind = function (context, ...bindArgs) {
//     const func = this;
//     context = context || window;
//     if(typeof func !== 'function') {
//         throw new TypeError('Bind must be called on a function');
//     }
//     return function (...callArgs) {
//         let args = bindArgs.concat(callArgs);
//         if(this instanceof func) {
//             return new func(...args);
//         }
//         return func.call(context, ...args);
//     }
// };
//
// Function.prototype.call = function (context, ...args) {
//     context = context || window;
//     context.func = this;
//     if(typeof context.func !== 'function') {
//         throw new TypeError('call must be called on a function');
//     }
//     let res = context.func(...args);
//     delete context.func;
//     return res;
// };
//
// function _instanceof(a, b) {
//     while(a) {
//         if(a.__proto__ === b.prototype) return true;
//         a = a.__proto__;
//     }
//     return false;
// }

//节流
function throttle(func, wait) {
    let timer = null;
    return function (...args) {
        if(!timer) {
            func(...args);
            timer = setTimeout(()=>{
                timer = null;
            }, wait);
        }
    }
}

//防抖
function debounce(func, wait) {
    let timer = null;

    return function(...args){
        if(timer) clearTimeout(timer);
        timer = setTimeout(() => {
            func(...args);
        }, wait);
    }
}

//Promise
const PENDING = 1;
const FULFILED = 2;
const REJECTED = 3;
class MyPromise1 {
    constructor(executor) {
        this.resolveQueue = [];
        this.rejectQueue = [];
        this.state = PENDING;
        this.val = undefined;
        this.resolve = this.resolve.bind(this);
        this.reject = this.reject.bind(this);
        this.then = this.then.bind(this);
        try {
            executor(this.resolve, this.reject)
        }catch(err) {
            this.reject(err)
        }
    }
    
    resolve(val) {
        if(this.state === PENDING) {
            setTimeout(()=>{
                this.state = FULFILED;
                this.val = val;
                this.resolveQueue.forEach(cb => cb(val));
            });
        }
    }
    reject(err) {
        if(this.state === PENDING) {
            setTimeout(() => {
                this.state = REJECTED;
                this.val = err;
                this.rejectQueue.forEach(cb => cb(err));
            })
        }
    }
    then(onResolve, onReject) {
        onResolve = typeof onResolve === 'function' ? onResolve : (v=>v);
        onReject = typeof onReject === 'function' ? onReject : (e=>{throw  e});
        if (this.state === FULFILED) {
        }
    }
}


const promise = new MyPromise1(function (resolve, reject) {
    console.log('Promise');
    resolve()
});











// function MyPromise(executor) {
//     let self = this;
//     this.resolveQueue = [];
//     this.rejectQueue = [];
//     this.state = PENDING;
//     this.val = undefined;
//     function resolve(val) {
//         if (self.state === PENDING) {
//             setTimeout(() => {
//                 self.state = FULFILLED;
//                 self.val = val;
//                 self.resolveQueue.forEach(cb => cb(val));
//             });
//         }
//     }
//     function reject(err) {
//         if (self.state === PENDING) {
//             setTimeout(() => {
//                 self.state = REJECTED;
//                 self.val = err;
//                 self.rejectQueue.forEach(cb => cb(err));
//             });
//         }
//     }
//     try {
//         // 回调是异步执行 函数是同步执行
//         executor(resolve, reject);
//     } catch(err) {
//         reject(err);
//     }
// }
//
// MyPromise.prototype.then = function(onResolve, onReject) {
//     let self = this;
//     // 不传值的话默认是一个返回原值的函数
//     onResolve = typeof onResolve === 'function' ? onResolve : (v => v); 
//     onReject = typeof onReject === 'function' ? onReject : (e => { throw e });
//     if (self.state === FULFILLED) {
//         return new MyPromise(function(resolve, reject) {
//             setTimeout(() => {
//                 try {
//                     let x = onResolve(self.val);
//                     if (x instanceof MyPromise) {
//                         x.then(resolve);
//                     } else {
//                         resolve(x);
//                     }
//                 } catch(e) {
//                     reject(e);
//                 }
//             });
//         });
//     }
//
//     if (self.state === REJECTED) {
//         return new MyPromise(function(resolve, reject) {
//             setTimeout(() => {
//                 try {
//                     let x = onReject(self.val);
//                     if (x instanceof MyPromise) {
//                         x.then(resolve);
//                     } else {
//                         resolve(x);
//                     }
//                 } catch(e) {
//                     reject(e);
//                 }
//             });
//         });
//     }
//    
//     if (self.state === PENDING) {
//         return new MyPromise(function(resolve, reject) {
//             self.resolveQueue.push((val) => {
//                 try {
//                     let x = onResolve(val);
//                     if (x instanceof MyPromise) {
//                         x.then(resolve);
//                     } else {
//                         resolve(x);
//                     }
//                 } catch(e) {
//                     reject(e);
//                 }
//             });
//             self.rejectQueue.push((val) => {
//                 try {
//                     let x = onReject(val);
//                     if (x instanceof MyPromise) {
//                         x.then(resolve);
//                     } else {
//                         resolve(x);
//                     }
//                 } catch(e) {
//                     reject(e);
//                 }
//             });
//         });
//     }
// };
//
// MyPromise.prototype.catch = function(onReject) {
//     return this.then(null, onReject);
// };
//
// MyPromise.all = function(promises) {
//     return new MyPromise(function(resolve, reject) {
//         let cnt = 0;
//         let result = [];
//         for (let i = 0; i < promises.length; i++) {
//             promises[i].then(res => {
//                 result[i] = res;
//                 if (++cnt === promises.length) resolve(result);
//             }, err => {
//                 reject(err);
//             })
//         }
//     });
// };
//
// MyPromise.race = function(promises) {
//     return new MyPromise(function(resolve, reject) {
//         for (let i = 0; i < promises.length; i++) {
//             promises[i].then(resolve, reject);
//         }
//     });
// };
//
// MyPromise.resolve = function(val) {
//     return new MyPromise(function(resolve, reject) {
//         resolve(val);
//     });
// };
//
// MyPromise.reject = function(err) {
//     return new MyPromise(function(resolve, reject) {
//         reject(err);
//     })
// };
//
